package com.xbongbong.crm.perform.query.detail;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.abstracts.AbstractCrmDetailTopInfoService;
import com.xbongbong.crm.help.StageAverageStayTimeHelp;
import com.xbongbong.crm.service.permission.OpportunityPermissionServiceImpl;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.enums.StageTypeEnum;
import com.xbongbong.paas.enums.UnitEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.LinkListPojo;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FormDataHelp;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.CustomerUserPojo;
import com.xbongbong.paas.pojo.DataDetailPojo;
import com.xbongbong.paas.pojo.DetailTabPojo;
import com.xbongbong.paas.pojo.DetailTitlePojo;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.HandelDetailPojo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.WorkFlowPojo;
import com.xbongbong.paas.pojo.vo.FormDataGetVO;
import com.xbongbong.paas.pojo.vo.ParseSingleRowDataVO;
import com.xbongbong.paas.service.BusinessButtonService;
import com.xbongbong.paas.service.DetailTabConfigService;
import com.xbongbong.paas.service.LinkListService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.TitleUtil;
import com.xbongbong.parent.parse.data.FormDataGetAnalysisDataHelp;
import com.xbongbong.pro.appdetail.pojo.MobileDetailDirectBlockPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailManagerBlockPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailMoneyItemPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailScriptPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailStatusPojo;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.form.pojo.TopPermissionsPoJo;
import com.xbongbong.pro.formdata.pojo.dto.FormDataDetailDTO;
import com.xbongbong.pro.formdata.pojo.dto.SaasAnalysisDataDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.message.model.PushModel;
import com.xbongbong.pro.permission.pojo.dto.VerifyViewPermissionDTO;
import com.xbongbong.pro.statistic.enums.ChartCategoryAliasEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.OpportunityFocusEntity;
import com.xbongbong.saas.domain.entity.OpportunityUserEntity;
import com.xbongbong.saas.domain.entity.SaleStageEntity;
import com.xbongbong.saas.domain.entity.WorkOrderFormEntity;
import com.xbongbong.saas.enums.BusinessDetailButtonEnum;
import com.xbongbong.saas.enums.BusinessDetailTabEnum;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.DetailTabEnum;
import com.xbongbong.saas.enums.SaasButtonEnum;
import com.xbongbong.saas.enums.WorkFlowEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.enums.dictionary.ArchivedEnum;
import com.xbongbong.saas.model.OpportunityFocusModel;
import com.xbongbong.saas.model.OpportunityModel;
import com.xbongbong.saas.model.OpportunityUserModel;
import com.xbongbong.saas.model.SaleStageModel;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.saas.service.toolbox.help.AttrDecimalPrecisionHelper;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.util.NameUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;

/**
 * @author 吴峰
 * @date 2022/05/25 13:59
 */
@Service("opportunityDetailTopInfoServiceImpl")
@Slf4j
public class OpportunityDetailTopInfoServiceImpl extends AbstractCrmDetailTopInfoService {

    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private OpportunityPermissionServiceImpl opportunityPermissionService;
    @Resource
    private OpportunityModel opportunityModel;
    @Resource
    private FormDataGetAnalysisDataHelp formDataGetAnalysisDataHelp;
    @Resource
    private OpportunityFocusModel opportunityFocusModel;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private LinkListService linkListService;
    @Resource
    private PackageHelp packageHelp;
    @Resource
    private DetailTabConfigService detailTabConfigService;
    @Resource
    private StageAverageStayTimeHelp stageAverageStayTimeHelp;
    @Resource
    private SaleStageModel saleStageModel;
    @Resource
    private OpportunityUserModel opportunityUserModel;
    @Resource
    private UserModel userModel;
    @Resource
    private FormDataHelp formDataHelp;
    @Resource
    private PushModel pushModel;
    @Resource
    private UserTeamHelp userTeamHelp;
    @Resource
    private BusinessButtonService businessButtonService;
    @Resource
    private CommonHelp commonHelp;

    @Override
    public List<Integer> businessType() {
        return Arrays.asList(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode());
    }

    @Override
    public void checkPermission(PaasFormEntityExt formEntity, PaasFormDataEntityExt paasFormDataEntityExt, UserVO loginUser, Integer businessType) throws XbbException {
        if (loginUser.isMaxDataPermission()){
            return;
        }
        //校验用户是否有查看权限
        verifyQueryPermission(businessType, loginUser, formEntity.getSaasMark(), formEntity.getMenuId(), paasFormDataEntityExt.getFlowStatus());
        //团队权限&共享权限校验
        opportunityPermissionService.checkPermission(formEntity, paasFormDataEntityExt, loginUser, businessType);

    }


    @Override
    public JSONObject analysisData(PaasFormDataEntityExt paasFormDataEntityExt, HandlerExplainDTO handlerExplainDTO, HandlerExplainVO handlerExplainVO) throws XbbException {
        Long formId = paasFormDataEntityExt.getFormId();
        List<FieldAttrEntity> list = handlerExplainVO.getHeadList();
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(list.size());
        list.forEach(item->explainMap.put(item.getAttr(), item));

        ParseSingleRowDataVO parseSingleRowDataVO = commonAnalysisData(paasFormDataEntityExt, handlerExplainDTO, handlerExplainVO, list, explainMap);
        JSONObject data = parseSingleRowDataVO.getResult();
        SaasAnalysisDataDTO saasAnalysisDataDTO = new SaasAnalysisDataDTO();
        BeanUtil.copyProperties(handlerExplainDTO, saasAnalysisDataDTO);
        saasAnalysisDataDTO.setFormId(formId);
        opportunityModel.formatData(saasAnalysisDataDTO, data);
        //处理千分位
        FormDataGetVO formDataGetVO = new FormDataGetVO();
        formDataGetVO.setData(data);
        formDataGetAnalysisDataHelp.analysisGetOfThousandBits(formDataGetVO, list, false);
        return data;
    }

    @Override
    public List<SummaryDataPoJo> getSummaryList(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {

        String corpid = formDataDetailDTO.getCorpid();
        Long formId = formEntity.getId();
        List<SummaryDataPoJo> summaryList = ExplainUtil.getSpecialSummaryList(formEntity.getSummaryList(), data, explainMap, formData);
        for (SummaryDataPoJo summaryItem : summaryList) {
            if (Objects.equals(summaryItem.getAttr(), FieldTypeEnum.SERIALNO.getAlias())) {
                summaryItem.setAttrName(SalesOpportunityEnum.SERIAL_NO.getAttrName());
            } else if ( Objects.equals(summaryItem.getAttr(), SalesOpportunityEnum.ESTIMATE_END_TIME.getAttr()) ) {
                List<Object> valueList = summaryItem.getValue();
                if ( valueList.isEmpty() ) {
                    break;
                }
                String valueKey = (String) valueList.get(0);
                Long estimate = DateTimeUtil.getInt(valueKey, DateTimeUtil.SDFDate);
                if ( estimate < DateTimeUtil.getTodayInt() ) {
                    String nameOrCode = data.getString(SalesOpportunityEnum.SALE_STAGE.getAttr());
                    SaleStageEntity saleStage = null;
                    if (StringUtil.isNotEmpty(nameOrCode)) {
                        saleStage = saleStageModel.getByCode(corpid, formId, nameOrCode);
                    }
                    List<Integer> noRemindCode = Arrays.asList(StageTypeEnum.SUCCESS_STAGE.getType(),StageTypeEnum.FAIL_STAGE.getType(),StageTypeEnum.CANCEL_STAGE.getType());
                    if(Objects.isNull(saleStage) || !noRemindCode.contains(saleStage.getType())) {
                        // 预计结束时间延期标红
                        summaryItem.setStatus("delay");
                    }
                }
                break;
            }
        }
        specialTransferKeyToShowValue(corpid, summaryList, formEntity.getBusinessType(), data, formId);
        return summaryList;
    }

    @Override
    public List<SummaryDataPoJo> getLabelList(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        // 解析标签
        return ExplainUtil.getSpecialSummaryList(formEntity.getLabelsList(), data, explainMap, formData);
    }

    @Override
    public List<FormTitlePoJo> getTitleList(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {

        return ExplainUtil.getSpecailFormTitle(JSONArray.parseArray(formEntity.getCustomTitle()), explainMap, data, list, formData);
    }

    @Override
    public List<MobileDetailMoneyItemPojo> getMobileDetailMoneyInfo(Integer distributorMark, String corpid, String userId, Integer businessType, Integer subBusinessType, Long dataId, JSONObject data, Map<String, FieldAttrEntity> explainMap, UserVO loginUser, PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException {
        List<MobileDetailMoneyItemPojo> moneyItemList = new ArrayList<>();
        String salesUnit = UnitEnum.MONEY.getName();
        FieldAttrEntity fieldAttrEntity = explainMap.get(SalesOpportunityEnum.ESTIMATE_AMOUNT.getAttr());
        if (Objects.nonNull(fieldAttrEntity) && Objects.equals(fieldAttrEntity.getVisible(), BasicConstant.ONE)) {
            Object estimateAmount = AttrDecimalPrecisionHelper.moneyParseThrousandth(fieldAttrEntity,paasFormDataEntityExt.getData(),SalesOpportunityEnum.ESTIMATE_AMOUNT.getAttr());
            moneyItemList.add(new MobileDetailMoneyItemPojo(fieldAttrEntity.getAttrName() + "/" + salesUnit, estimateAmount, false));
        }
        FieldAttrEntity costFieldAttrEntity = explainMap.get(SalesOpportunityEnum.COST.getAttr());
        if (Objects.nonNull(costFieldAttrEntity) && Objects.equals(costFieldAttrEntity.getVisible(), BasicConstant.ONE)) {
            Object costAmount = AttrDecimalPrecisionHelper.moneyParseThrousandth(costFieldAttrEntity,paasFormDataEntityExt.getData(),SalesOpportunityEnum.COST.getAttr());
            moneyItemList.add(new MobileDetailMoneyItemPojo(costFieldAttrEntity.getAttrName() + "/" + salesUnit, costAmount, false));
        }
        FieldAttrEntity grossProfitFieldAttrEntity = explainMap.get(SalesOpportunityEnum.GROSS_PROFIT.getAttr());
        if (Objects.nonNull(grossProfitFieldAttrEntity) && Objects.equals(grossProfitFieldAttrEntity.getVisible(), BasicConstant.ONE)) {
            Object grossProfitAmount = AttrDecimalPrecisionHelper.moneyParseThrousandth(grossProfitFieldAttrEntity,paasFormDataEntityExt.getData(),SalesOpportunityEnum.GROSS_PROFIT.getAttr());
            moneyItemList.add(new MobileDetailMoneyItemPojo(grossProfitFieldAttrEntity.getAttrName() + "/" + salesUnit,grossProfitAmount, false));
        }
        FieldAttrEntity grossProfitRateFieldAttrEntity = explainMap.get(SalesOpportunityEnum.GROSS_PROFIT_RATE.getAttr());
        if (Objects.nonNull(grossProfitRateFieldAttrEntity) && Objects.equals(grossProfitRateFieldAttrEntity.getVisible(), BasicConstant.ONE)) {
            moneyItemList.add(new MobileDetailMoneyItemPojo(grossProfitRateFieldAttrEntity.getAttrName() + "/%", paasFormDataEntityExt.getData().getString(SalesOpportunityEnum.GROSS_PROFIT_RATE.getAttr()), false));
        }
        return moneyItemList;
    }

    @Override
    public JSONArray getBottomBlockInfo(String corpid, String userId, Integer businessType, PaasFormEntityExt formEntity, Long dataId, JSONObject data, Map<String, FieldAttrEntity> explainMap, PaasFormDataEntityExt entityExt, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", 0);
        param.put("opportunityId", dataId);
        List<OpportunityUserEntity> opportunityUserList = opportunityUserModel.findEntitys(param);
        Set<String> userIdIn = new HashSet<>();
        opportunityUserList.forEach(item -> userIdIn.add(item.getUserId()));
        List<UserEntity> userEntityList = userModel.getByUserIdIn(corpid, userIdIn, true);
        Map<String, UserEntity> userMap = new HashMap<>(userEntityList.size());
        userEntityList.forEach(item -> userMap.put(item.getUserId(), item));
        List<CustomerUserPojo> userPojoList = new ArrayList<>();
        opportunityUserList.forEach(item -> {
            UserEntity userEntity = userMap.get(item.getUserId());
            if (userEntity != null) {
                CustomerUserPojo customerUserPojo = new CustomerUserPojo();
                customerUserPojo.setUserId(userEntity.getUserId());
                customerUserPojo.setName(userEntity.getName());
                customerUserPojo.setAvatar(userEntity.getAvatar());
                customerUserPojo.setIsMain(item.getIsMain());
                userPojoList.add(customerUserPojo);
            }
        });
        JSONArray bottomBlockInfo = new JSONArray();
        bottomBlockInfo.add(new MobileDetailManagerBlockPojo(userPojoList));

        JSONObject sourceData = entityExt.getData();
        Long customerId = FastJsonHelper.getLongOrDefaultFromFormData(sourceData, SalesOpportunityEnum.CUSTOMER_NAME.getAttr(), 0L);
        if(Objects.nonNull(customerId)){
            PaasFormDataEntityExt paasFormDataEntity = formDataHelp.getFormData(corpid, SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), customerId);
            if(Objects.nonNull(paasFormDataEntity)){
                Long formId = paasFormDataEntity.getFormId();
                String customerName = FastJsonHelper.getStringOrDefaultFromFormData(sourceData, SalesOpportunityEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(), "");
                bottomBlockInfo.add(new MobileDetailDirectBlockPojo(customerId, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), customerName,formId));
            }
        }
        return bottomBlockInfo;
    }

    @Override
    public List<MobileDetailScriptPojo> getDetailShowScript(Integer businessType, UserVO loginUser, PaasFormDataEntityExt paasFormDataEntityExt, Map<String, FieldAttrEntity> explainMap) throws XbbException {

        return setDetailShowScript(paasFormDataEntityExt, businessType, paasFormDataEntityExt.getData(), explainMap, SalesOpportunityEnum.ESTIMATE_AMOUNT.getAttr());
    }

    @Override
    public MobileDetailStatusPojo getDetailShowStatus(Integer businessType, JSONObject data) throws XbbException {
        MobileDetailStatusPojo mobileDetailStatusPojo = new MobileDetailStatusPojo();
        Integer archived = getIntegerOrDefaultFromFormData(data, SalesOpportunityEnum.IS_ARCHIVED.getAttr(), 2);
        mobileDetailStatusPojo.setName("archived");
        mobileDetailStatusPojo.setValue(archived);
        return mobileDetailStatusPojo;
    }

    @Override
    public Map<String, Object> getDetailShowOperation(String corpid, String userId, Integer businessType, Long dataId, JSONObject data) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        // 关注
        boolean isOppShare;
        try {
            isOppShare = companyConfigModel.hasBeenEnable(corpid, CompanyConfigEnum.SHARE_FOCUS_OPPORTUNITY.getAlias(), BasicConstant.IS_USE.toString());
        } catch (XbbException e) {
            isOppShare = Objects.equals(CompanyConfigEnum.SHARE_FOCUS_OPPORTUNITY.getValue(), BasicConstant.IS_USE.toString());
        }
        Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid", corpid);
        if(!isOppShare) {
            map.put("userId", userId);
        }
        map.put("opportunityIdIn", Collections.singletonList(dataId));
        map.put("del", DelEnum.NORMAL.getDel());
        map.put("focus", BasicConstant.IS_USE);
        List<OpportunityFocusEntity> opportunityFocusEntityList = opportunityFocusModel.findEntitys(map);
        Integer isFocus = opportunityFocusEntityList != null && opportunityFocusEntityList.size() > 0 ? BasicConstant.IS_USE : BasicConstant.NO_USE;
        param.put("isFocus", isFocus);
        //有提醒的机会
        Collection<Long> pushNotifyList= pushModel.getPushNotify(Collections.singletonList(dataId), corpid, XbbRefTypeEnum.SALES_OPPORTUNITY.getCode());
        if (!pushNotifyList.isEmpty()) {
            param.put("message", true);
        }
        return param;
    }

    @Override
    public JSONObject returnSaasObject(String corpid, Integer businessType, UserVO userVO, PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException {
        JSONObject saasReturnObj = new JSONObject();
        //快捷新建跟进记录tab栏显示与否
        saasReturnObj.put(StringConstant.QUICKFLLOWTAB, true);
        //动态显示与否
        saasReturnObj.put(StringConstant.DYNAMIC, true);
        //动态名称
        saasReturnObj.put(StringConstant.DYNAMICNAME, I18nMessageUtil.getMessage(I18nStringConstant.DYNAMIC));
        return saasReturnObj;
    }


    @Override
    public List<ButtonPojo> handleDetailButton(FormDataDetailDTO formDataDetailDTO, HandelDetailPojo handelDetailPojo, PaasFormDataEntityExt formData, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        UserVO userVO = formDataDetailDTO.getLoginUser();
        Integer businessType = formDataDetailDTO.getBusinessType();
        JSONObject dataList = formData.getData();
        List<ButtonPojo> buttonPojoList = new ArrayList<>();
        List<BusinessDetailButtonEnum> buttonEnumList = BusinessDetailButtonEnum.getByBusinessTypeAndPermission(businessType, userVO.getPermSet());
        Integer archived = getIntegerOrDefaultFromFormData(dataList, SalesOpportunityEnum.IS_ARCHIVED.getAttr(), ArchivedEnum.UN_ARCHIVED.getCode());
        VerifyViewPermissionDTO verifyViewPermissionDTO = new VerifyViewPermissionDTO(userVO, formData);
        boolean perTag = commonPermissionHelp.checkEditPermissionWithoutShareEdit(formDataDetailDTO, verifyViewPermissionDTO, explainMap);
        for (BusinessDetailButtonEnum buttonEnum : buttonEnumList) {
            if (Objects.equals(archived, ArchivedEnum.UN_ARCHIVED.getCode()) && Objects.equals(buttonEnum, BusinessDetailButtonEnum.OPPORTUNITY_CANCEL_ARCHIVED)) {
                continue;
            } else if (Objects.equals(archived, ArchivedEnum.ARCHIVED.getCode()) && Objects.equals(buttonEnum, BusinessDetailButtonEnum.OPPORTUNITY_ARCHIVED)) {
                continue;
            }
            ButtonPojo buttonPojo = new ButtonPojo();
            SaasButtonEnum saasButtonEnum = buttonEnum.getAnEnum();
            if (!perTag && Objects.equals(SaasButtonEnum.EDIT.getAttr(), saasButtonEnum.getAttr())) {
                continue;
            }
            BeanUtil.copyProperties(saasButtonEnum, buttonPojo);
            buttonPojo.setLinkBusinessType(buttonEnum.getLinkBusinessType());
            buttonPojoList.add(buttonPojo);
        }
        return buttonPojoList;
    }


    @Override
    public DetailTitlePojo handleDetailFocus(FormDataDetailDTO formDataDetailDTO, Integer businessType, PaasFormDataEntityExt paasFormDataEntityExt, String userId) throws XbbException {
        boolean isOppShare;
        String corpid = formDataDetailDTO.getCorpid();
        try {
            isOppShare = companyConfigModel.hasBeenEnable(corpid, CompanyConfigEnum.SHARE_FOCUS_OPPORTUNITY.getAlias(), BasicConstant.IS_USE.toString());
        } catch (XbbException e) {
            isOppShare = Objects.equals(CompanyConfigEnum.SHARE_FOCUS_OPPORTUNITY.getValue(), BasicConstant.IS_USE.toString());
        }
        Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid", corpid);
        if (!isOppShare) {
            map.put("userId", userId);
        }
        map.put("opportunityIdIn", Collections.singletonList(paasFormDataEntityExt.getId()));
        map.put("del", DelEnum.NORMAL.getDel());
        map.put("focus", BasicConstant.IS_USE);
        List<OpportunityFocusEntity> opportunityFocusEntityList = opportunityFocusModel.findEntitys(map);
        Integer isFocus = opportunityFocusEntityList != null && opportunityFocusEntityList.size() > 0 ? BasicConstant.IS_USE : BasicConstant.NO_USE;
        DetailTitlePojo detailTitlePojo = new DetailTitlePojo();
        detailTitlePojo.setIsFocus(isFocus);
        return detailTitlePojo;
    }

    @Override
    public List<WorkFlowPojo> webHandleDetailWorkFlow(HandelDetailPojo handelDetailPojo, PaasFormEntityExt formEntity, PaasFormDataEntityExt formData) throws XbbException {
        UserVO userVO = handelDetailPojo.getLoginUser();
        Set<String> permSet = userVO.getPermSet();
        List<WorkFlowEnum> workFlowEnumList = WorkFlowEnum.getByBusinessTypeAndPermission(handelDetailPojo.getBusinessType(), userVO.getPermSet());
        // 获取对应businessType的alias
        List<String> aliasIn = WorkFlowEnum.getAliasIn(workFlowEnumList);
        String corpid = formData.getCorpid();
        Integer businessType = handelDetailPojo.getBusinessType();

        Map<Integer, String> paasBusinessTypeToName = paasMenuModel.getMenuNameByAlias(aliasIn, corpid, businessType);
        //工单未开，以及没有可以用的工单模板，移除关联新建工单
        boolean workOrderEnable = paasAppModel.validateAppEnable(null, XbbRefTypeEnum.WORK_ORDER.getAlias(), SaasMarkEnum.SAAS.getCode(), corpid);
        List<WorkOrderFormEntity>  workOrderEnableForms = workOrderFormModel.getTemplateWithPermission(corpid, userVO, null, null);
        if (!workOrderEnable || (Objects.nonNull(workOrderEnableForms) && workOrderEnableForms.isEmpty())) {
            workFlowEnumList.remove(WorkFlowEnum.OPPORTUNITY_WORK_ORDER);
        }
        List<WorkFlowPojo> workFlowPojoList = new ArrayList<>();
        Integer feeType = packageHelp.getFeeType(corpid);

        for (WorkFlowEnum workFlowEnum : workFlowEnumList) {
            if (!Objects.equals(PackageTypeEnum.ULTIMATE.getType(), feeType)
                    && Objects.equals(workFlowEnum,WorkFlowEnum.OPPORTUNITY_LINK_COMPETITOR)){
                // 低版本移除竞争对手操作
               continue;
            }
            WorkFlowPojo workFlowPojo = new WorkFlowPojo();
            BeanUtil.copyProperties(workFlowEnum, workFlowPojo);
            NameUtil.changeValue(paasBusinessTypeToName, workFlowPojo);
            workFlowPojoList.add(workFlowPojo);
        }
        List<LinkListPojo> linkList = JSONArray.parseArray(formEntity.getAssociationList(), LinkListPojo.class);
        workFlowPojoList.addAll(linkListService.getCommonButton(linkList, formData.getDel(), handelDetailPojo.getLoginUser(), formData.getAppId(), formData.getFormId(), handelDetailPojo.getBusinessType(), SaasMarkEnum.SAAS.getCode(), corpid));
        return workFlowPojoList;
    }

    @Override
    public List<TopPermissionsPoJo> dingtalkHandleDetailWorkFlow(HandelDetailPojo handelDetailPojo, PaasFormEntityExt formEntity, PaasFormDataEntityExt formData, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        String corpid = formEntity.getCorpid();
        UserVO userVO = handelDetailPojo.getLoginUser();
        Integer businessType = formEntity.getBusinessType();
        JSONObject dataList = formData.getData();
        List<WorkFlowEnum> workFlowEnumList = WorkFlowEnum.getByBusinessTypeAndPermissionForDingtalk(businessType, userVO.getPermSet());

        List<String> aliasIn = new ArrayList<>();
        workFlowEnumList.forEach(item -> aliasIn.add(XbbRefTypeEnum.getByCode(item.getBusinessType()).getAlias()));
        Map<Integer, String> paasBusinessTypeToName = paasMenuModel.getMenuNameByAlias(aliasIn, corpid, businessType);

        List<TopPermissionsPoJo> topPermissions = businessButtonService.dingtalkDetailCommon(userVO, formEntity, explainMap, formData);
        Integer isOpportunityArchived = getIntegerOrDefaultFromFormData(dataList, SalesOpportunityEnum.IS_ARCHIVED.getAttr(), BasicConstant.ZERO);
        for (WorkFlowEnum workFlowEnum : workFlowEnumList) {
//            if (!hasUpdate && (Objects.equals(workFlowEnum, WorkFlowEnum.OPPORTUNITY_ARCHIVED) || Objects.equals(workFlowEnum, WorkFlowEnum.OPPORTUNITY_CANCEL_ARCHIVED))) {
//                continue;
//            }
            if (Objects.equals(isOpportunityArchived, ArchivedEnum.ARCHIVED.getCode()) && Objects.equals(workFlowEnum, WorkFlowEnum.OPPORTUNITY_ARCHIVED)) {
                continue;
            }
            if (Objects.equals(isOpportunityArchived, ArchivedEnum.UN_ARCHIVED.getCode()) && Objects.equals(workFlowEnum, WorkFlowEnum.OPPORTUNITY_CANCEL_ARCHIVED)) {
                continue;
            }
            TopPermissionsPoJo topPermissionsPoJo = new TopPermissionsPoJo();
            BeanUtil.copyProperties(workFlowEnum, topPermissionsPoJo);
            if (Objects.equals(workFlowEnum.getFormRelation(), BasicConstant.ONE)) {
                NameUtil.changeValue(paasBusinessTypeToName, topPermissionsPoJo);
            }
            topPermissions.add(topPermissionsPoJo);
        }
        List<LinkListPojo> linkList = formEntity.getLinkListList();
        topPermissions.addAll(linkListService.getDingtalkCommonButton(linkList, formData.getDel(), userVO, formData.getAppId(), formData.getFormId(), businessType, formEntity.getSaasMark(), corpid));

        return topPermissions;
    }

    @Override
    public DataDetailPojo handleDetailData(Integer businessType, PaasFormDataEntityExt formData, String userId, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        DataDetailPojo dataDetailPojo = new DataDetailPojo();
        // 外链
        Integer outerLinkShare = setOuterLinkShare(handlerExplainDTO.getCorpid(), formData.getFormId());
        dataDetailPojo.setHasOuterLinkShare(outerLinkShare);
        return dataDetailPojo;
    }



    @Override
    public JSONArray getSecondTitleList(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        List<SummaryDataPoJo> summaryList = ExplainUtil.getSpecialSummaryList(formEntity.getSummaryList(), data, explainMap, formData);
        JSONArray secondTitle =  getSecondTitleList(summaryList, data, formDataDetailDTO.getCorpid(), formEntity.getId());
        String opStayTimeStr = stageAverageStayTimeHelp.getAverageStayTime(formDataDetailDTO.getSaasMark(), formDataDetailDTO.getBusinessType(), formDataDetailDTO.getCorpid(), formEntity.getId(), formData.getDataId(), formData.getData());
//                    String opStayTimeStr = opportunityStageLogModel.getAverageStayTime(corpid, dataId);
        if (opStayTimeStr != null) {
            JSONObject opporObj3 = ExplainUtil.getSecondTitleObj(false, I18nMessageUtil.getMessage(I18nStringConstant.STAY_LONG_TIME), opStayTimeStr);
            secondTitle.add(opporObj3);
        }
        return secondTitle;
    }

    @Override
    public JSONObject getSecondTitle(SummaryDataPoJo pojo, Object value, JSONObject data, String corpid, Long formId) {
        JSONObject secondTitle = new JSONObject();
        try {
            if (Objects.equals(pojo.getAttr(), SalesOpportunityEnum.ESTIMATE_END_TIME.getAttr())) {
                if (Objects.isNull(pojo.getValue()) || (Objects.nonNull(pojo.getValue()) && pojo.getValue().isEmpty())) {
                    return ExplainUtil.getSecondTitleObj(false, pojo.getAttrName(), value);
                } else {
                    Object object1 = pojo.getValue().get(0);
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    Date date = dateFormat.parse(object1.toString());
                    dateFormat.format(date);
                    long a = date.getTime() / 1000;
                    long b = DateUtil.getTodayInt();
                    if (a < b) {
                        List<Integer> noRemindCode = Arrays.asList(StageTypeEnum.SUCCESS_STAGE.getType(),StageTypeEnum.FAIL_STAGE.getType(),StageTypeEnum.CANCEL_STAGE.getType());
                        JSONObject object = new JSONObject();
                        SaleStageEntity saleStage = null;
                        String code = data.getString(SalesOpportunityEnum.SALE_STAGE.getAttr());
                        if (StringUtil.isNotEmpty(code)) {
                            saleStage = saleStageModel.getByCode(corpid, formId, code);
                        }
                        if(saleStage !=null && noRemindCode.contains(saleStage.getType())){
                            object.put("type", "black");
                        }else {
                            object.put("type", "red");
                        }
                        object.put("name", pojo.getAttrName());
                        object.put("value", object1);
                        return object;
                    } else {
                        return ExplainUtil.getSecondTitleObj(false, pojo.getAttrName(), value);
                    }
                }
            }else {
                //负责人isTeam为true前端需要
                if (Objects.equals(pojo.getAttrName(), WorkOrderEnum.OWNER_ID.getAttrName()) || Objects.equals(pojo.getAttrName(), WorkOrderEnum.COUSERID.getAttrName())) {
                    return ExplainUtil.getSecondTitleObj(true, pojo.getAttrName(), value);
                } else {
                    return ExplainUtil.getSecondTitleObj(false, pojo.getAttrName(), value);
                }
            }
        } catch (Exception e) {

        }
        return secondTitle;
    }

    @Override
    public JSONArray getTagList(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        String corpid = formDataDetailDTO.getCorpid();
        Integer businessType = formEntity.getBusinessType();
        Long dataId = formData.getId();
        String userId = formDataDetailDTO.getUserId();
        List<SummaryDataPoJo> labelsList = getLabelList(formDataDetailDTO, formData, formEntity, list, explainMap, data);
        JSONArray tags = getTags(labelsList, corpid, businessType, dataId, userId);
        return tags;
    }

    @Override
    public String getTitle(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        List<FormTitlePoJo> formTitleList = getTitleList(formDataDetailDTO, formData, formEntity, list, explainMap, data);
        return TitleUtil.getWebTitle(formTitleList);
    }

    @Override
    public List<DetailTabPojo> handleDetailTab(HandelDetailPojo handelDetailPojo, PaasFormEntityExt formEntity, PaasFormDataEntityExt formData, Map<String, FieldAttrEntity> explainMap, HandlerExplainVO handlerExplainVO, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        UserVO userVO = handelDetailPojo.getLoginUser();
        String corpid = userVO.getCorpid();
        String userId = userVO.getUserId();
        Integer businessType = handelDetailPojo.getBusinessType();
        Set<String> permSet = userVO.getPermSet();

        List<BusinessDetailTabEnum>  tabEnumList = BusinessDetailTabEnum.getTabByBusinessTypeAndPermission(businessType, userVO.getPermSet(), handlerExplainDTO.getPlatform());
        //判断客户阶段是否开启
        boolean ifOpportunityStageOpen = CommonHelp.ifStageOpen(businessType, explainMap, handlerExplainDTO);
        // 判断关联产品字段是否可见
//                boolean salesOpportunityProduct = commonHelp.attrCanSee(SalesOpportunityEnum.PRODUCTS.getAttr(), explainMap, handlerExplainDTO);
        PaasMenuEntity oppQuotation = paasMenuModel.getByAlias(XbbRefTypeEnum.QUOTATION.getAlias(), null, corpid);
        boolean oppQuotationShow = oppQuotation != null && Objects.equals(oppQuotation.getEnable(), BasicConstant.ONE);

        PaasMenuEntity oppContract = paasMenuModel.getByAlias(XbbRefTypeEnum.CONTRACT.getAlias(), null, corpid);
        boolean oppContractShow = oppContract != null && Objects.equals(oppContract.getEnable(), BasicConstant.ONE);

        boolean linkCompetitorCanSee = commonHelp.attrCanSee(SalesOpportunityEnum.LINK_COMPETITOR.getAttr(), explainMap, handlerExplainDTO);

        // 旗舰版
        Integer feeType = packageHelp.getFeeType(corpid);
        boolean ultimateType = Objects.equals(PackageTypeEnum.ULTIMATE.getType(), feeType);
        // 获取对应businessType的alias
        List<String> aliasIn = BusinessDetailTabEnum.getAliasIn(tabEnumList);

        // 记录businessType与menuName的关系
        Map<Integer, String> paasBusinessTypeToName = paasMenuModel.getMenuNameByAlias(aliasIn, corpid, businessType);
        List<DetailTabPojo> tabPojoList = new ArrayList<>();
        for (BusinessDetailTabEnum tabEnum : tabEnumList) {
            // 移动端不需要阶段历史
            if (Objects.equals(tabEnum, BusinessDetailTabEnum.SALES_OPPORTUNITY_CUSTOMER_STAGE) && Objects.equals(handlerExplainDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
                continue;
            }
            if (!ifOpportunityStageOpen && Objects.equals(tabEnum, BusinessDetailTabEnum.SALES_OPPORTUNITY_CUSTOMER_STAGE)) {
                continue;
            }
            if (!oppContractShow && Objects.equals(tabEnum, BusinessDetailTabEnum.SALES_OPPORTUNITY_CONTRACT)) {
                // 合同菜单不开启，那么机会详情的合同tab也不开启
                continue;
            }
//                    if (!salesOpportunityProduct && Objects.equals(tabEnum, BusinessDetailTabEnum.SALES_OPPORTUNITY_PRODUCT_LIST)) {
//                        continue;
//                    }
            if (Objects.equals(tabEnum, BusinessDetailTabEnum.SALES_OPPORTUNITY_QUOTATION) && !oppQuotationShow) {
                continue;
            }
            // 非旗舰版无机会联系人
            if (!ultimateType && Objects.equals(tabEnum, BusinessDetailTabEnum.SALES_OPPORTUNITY_CONTACT)) {
                continue;
            }
            if ((!linkCompetitorCanSee || !ultimateType) && Objects.equals(tabEnum, BusinessDetailTabEnum.SALES_OPPORTUNITY_COMPETITOR)) {
                continue;
            }
            DetailTabPojo detailTabPojo = new DetailTabPojo();
            BeanUtil.copyProperties(tabEnum.getAnEnum(), detailTabPojo);
            NameUtil.changeTabEnumName(paasBusinessTypeToName, tabEnum, detailTabPojo);
            detailTabPojo.setAttr(detailTabPojo.getKey());
            if (Objects.equals(DetailTabEnum.WORK_ORDER_LOG.getKey(), detailTabPojo.getAttr())) {
                PaasMenuEntity paasMenuEntity = paasMenuModel.getByAlias(ChartCategoryAliasEnum.WORK_ORDER.getAlias(),corpid);
                if (Objects.nonNull(paasMenuEntity)) {
                    detailTabPojo.setName(paasMenuEntity.getName());
                }

            }
            tabPojoList.add(detailTabPojo);
        }
        handleTeamTab(tabPojoList, explainMap);
        List<LinkListPojo> linkList = JSONArray.parseArray(formEntity.getAssociationList(), LinkListPojo.class);
        handlerExplainVO.setAppId(formEntity.getAppId());
        handlerExplainVO.setFormId(formEntity.getId());
        // 公共tab
        tabPojoList.addAll(linkListService.commonTab(corpid, userVO, handlerExplainVO, handlerExplainDTO, businessType, formData.getDel(), linkList));
        // tab排序
        tabPojoList = detailTabConfigService.handleDetailTabSort(userVO.getUserId(), corpid, handlerExplainVO.getFormId(), businessType, tabPojoList);
        return tabPojoList;
    }

}
